// @ts-ignore
import axios from 'axios';
import { Loading } from 'element-ui';

const TIMEOUT = 15000;
let BASE_URL = '';

if (process.env.NODE_ENV === 'development') {
  // ==================开发环境API===================
  BASE_URL = '1241.12.1212.12';
} else if (process.env.NODE_ENV === 'testing') {
  BASE_URL = '***';
} else if (process.env.NODE_ENV === 'production') {
  // ==================正式环境API===================
  BASE_URL = process.env.BASE_URL;
}

const service = axios.create({
  baseURL: BASE_URL,
  timeout: TIMEOUT,
});

// request 拦截器
const requestConfig = (config: any) => {
  const token = window.localStorage.getItem('E-User-Token'); // 注意使用的时候需要引入cookie方法
  config.data = JSON.stringify(config.data);
  // 没有传入 自定义配置 headers，默认json ，传入则按传入的方式
  config.headers = {
    'Content-Type': 'application/json;charset=utf-8',
    'Accept': '*/*',
    'E-User-Token': token,
    ...config.headers,
  };
  return config;
};

// 响应成功拦截
const interceptorsRes = (response: any) => {
  if (response.data.refreshToken) {
    window.localStorage.setItem('E-User-Token', response.data.refreshToken);
  }
  const {
    data: {
      msg,
      success,
    },
  } = response;
  if (!success && msg) {
    console.log(success, msg);
  }
  return response;
};

const ERRCODE: any = {
  400: '错误请求',
  401: '未授权，请重新登录',
  403: '拒绝访问',
  404: '请求错误,未找到该资源',
  405: '请求方法未允许',
  408: '请求超时',
  500: '网络异常',
  501: '网络未实现',
  502: '网络错误',
  503: '服务不可用',
  504: '网络超时',
  505: 'http版本不支持该请求',
};

// 响应失败拦截
const interceptorsErr = (error: any) => {
  if (error && error.response) {
    const { status } = error.response;
    if (ERRCODE[status]) {
      error.message = ERRCODE[status];
    } else {
      error.message = `连接错误${error.response.status}`;
    }
  } else {
    if (error.code === 'ECONNABORTED') {
      console.log(error);
    } else {
      console.log(error);
    }
  }
  return Promise.reject(error);
};



localStorage.setItem('API_URL', BASE_URL || '');
service.defaults.withCredentials = true;
// axios.defaults.crossDomain = true;  // 允许跨域

// request请求拦截
service.interceptors.request.use(requestConfig, (error: any) => {
  return Promise.reject(error);
});

// response响应拦截器
service.interceptors.response.use(interceptorsRes, interceptorsErr);


let loading: any;
const target: any = document.querySelector('body');
const startLoading = () => {
  loading = Loading.service({
    lock: true,
    target,
    text: '加载中……',
    background: 'rgba(0, 0, 0, 0.7)',
  });
};


interface RequestOpt {
  isLoading: boolean;
  url: string;
  method: any;
  headers?: any;
  data?: any;
  responseType?: string;
  baseURL?: string;
  timeout?: number;
  successCall?: any;
  failMsg?: string;
  dataKey?: 'data' | 'datas' | 'models';
  successFilter?: any;
}


const endLoading = () => {
  loading.close();
};

export const AXIOS = (opt: RequestOpt) => {
  if (opt.isLoading) {
    startLoading();
  }
  return new Promise((resolve, reject) => {
    service({
      url: opt.url || '' ,
      method: opt.method,
      data: opt.data || {},
      baseURL: BASE_URL,
      timeout: TIMEOUT,
      headers: {
        ...opt.headers,
      },
    }).then((response: any) => {
      if (opt.isLoading) {
        endLoading();
      }
      resolve(response.data);
    }, (err: any) => {
      if (opt.isLoading) {
        endLoading();
      }
      reject(err);
    });
  });
};


const $https = {
  /**
   * 封装get方法
   * @param url
   * @param data
   * @returns {Promise}
   */
  get(url: any, params = {}, timeout: number = TIMEOUT, isLoading = false) {
    service.defaults.timeout = timeout;
    if (isLoading) {
      startLoading();
    }
    return new Promise((resolve, reject) => {
      service.get(url, {
        params,
      })
        .then((response) => {
          if (isLoading) {
            endLoading();
          }
          resolve(response.data);
        })
        .catch((err: any): void => {
          if (isLoading) {
            endLoading();
          }
          reject(err);
        });
    });
  },
  /**
   * 封装post请求
   * @param url
   * @param data
   * @returns {Promise}
   */
  post(url: string, data = {}, timeout = TIMEOUT, isLoading = false) {
    service.defaults.timeout = timeout;
    if (isLoading) {
      startLoading();
    }
    return new Promise((resolve, reject) => {
      service.post(url, data)
        .then((response) => {
          if (isLoading) {
            endLoading();
          }
          resolve(response.data);
        }, (err) => {
          if (isLoading) {
            endLoading();
          }
          reject(err);
        });
    });
  },
  /**
   * 封装patch请求
   * @param url
   * @param data
   * @returns {Promise}
   */
  patch(url: string, data = {}, timeout = TIMEOUT, isLoading = false) {
    service.defaults.timeout = timeout;
    if (isLoading) {
      startLoading();
    }
    return new Promise((resolve, reject) => {
      service.patch(url, data)
        .then((response) => {
          if (isLoading) {
            endLoading();
          }
          resolve(response.data);
        }, (err) => {
          if (isLoading) {
            endLoading();
          }
          reject(err);
        });
    });
  },
  /**
   * 封装put请求
   * @param url
   * @param data
   * @returns {Promise}
   */
  put(url: string, data = {}, timeout = TIMEOUT, isLoading = false) {
    service.defaults.timeout = timeout;
    if (isLoading) {
      startLoading();
    }
    return new Promise((resolve, reject) => {
      service.put(url, data)
        .then((response) => {
          if (isLoading) {
            endLoading();
          }
          resolve(response.data);
        }, (err) => {
          if (isLoading) {
            endLoading();
          }
          reject(err);
        });
    });
  },
  /**
   * 封装delete请求
   * @param url
   * @param data
   * @returns {Promise}
   */
  delete(url: string, params = {}, timeout = TIMEOUT, isLoading = false) {
    service.defaults.timeout = timeout;
    if (isLoading) {
      startLoading();
    }
    return new Promise((resolve, reject) => {
      service.delete(url, {
        params,
      })
        .then((response) => {
          if (isLoading) {
            endLoading();
          }
          resolve(response.data);
        }, (err) => {
          if (isLoading) {
            endLoading();
          }
          reject(err);
        });
    });
  },
};

export default $https;
